home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / minix / mdbtar~1.z / mdbtar~1 / mdbexp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-11  |  6.5 KB  |  351 lines

  1. /*
  2.  * mdbexp.c - MINIX expresion parser
  3.  *
  4.  * Written by Bruce D. Szablak
  5.  *
  6.  * This free software is provided for non-commerical use. No warrantee
  7.  * of fitness for any use is implied. You get what you pay for. Anyone
  8.  * may make modifications and distribute them, but please keep this header
  9.  * in the distribution. NOTE: A PORTION OF THIS FILE IS DERIVED FROM THE
  10.  * SOURCE TO ANM.C WHOSE AUTHOR IS UNKNOWN TO ME (AST?). BEWARE THAT
  11.  * OTHER RESTRICTIONS MAY APPLY.
  12.  */
  13.  
  14. #include <ctype.h>
  15. #include <setjmp.h>
  16. #include <stdio.h>
  17. #include "user.h"
  18. #include "out.h"
  19.  
  20. extern jmp_buf mainlp;
  21. extern curpid;
  22.  
  23. int nsyms;
  24. struct outname *nbufp = NULL;
  25. long value(), strtol(), lookup(), ptrace();
  26.  
  27. #define idchar(c) (isalpha(c) || isdigit(c) || (c) == '_')
  28.  
  29. char *
  30. addr_to_name(rel_addr, off_p)
  31.     long rel_addr, *off_p;
  32. {
  33.     register int i, l = 0, r = nsyms;
  34.  
  35.     while (l < r)
  36.     {
  37.         i = (l + r) >> 1;
  38.         if (rel_addr < nbufp[i].on_valu) r = i;
  39.         else if (rel_addr > nbufp[i].on_valu) l = i + 1;
  40.         else break;
  41.     }
  42.     if (l == nsyms || r == 0)
  43.     {
  44.         *off_p = rel_addr;
  45.         return "_start";
  46.     }
  47.     if (rel_addr < nbufp[i].on_valu) i--;
  48.     *off_p = rel_addr - nbufp[i].on_valu;
  49.     return nbufp[i].on_mptr;
  50. }
  51.  
  52. symbolic(addr, sep)
  53.     long addr;
  54.     char sep;
  55. {
  56.     long off;
  57.     extern long saddr, eaddr;
  58.  
  59.     if (addr < saddr || addr > eaddr)
  60.     {
  61.         printf("0x%lx%c", addr, sep);
  62.         return;
  63.     }
  64.     fputs(addr_to_name(addr - saddr, &off), stdout);
  65.     if (off) printf("+0x%lx", off);
  66.     fputc(sep, stdout);
  67. }
  68.  
  69. char *
  70. getexp(buf, exp_p, seg_p)
  71.     char *buf;
  72.     int *seg_p;
  73.     long *exp_p;
  74. {
  75.     extern char *skip();
  76.     long v = 0L;
  77.  
  78.     buf = skip(buf);
  79.     if ((isalpha(*buf) && (isspace(buf[1]) || buf[1]==';'))
  80.         || *buf=='\n' || *buf==';' || *buf=='/' || *buf == '!')
  81.     {
  82.         *exp_p = 0L;
  83.         return buf;
  84.     }
  85.     v = value(buf, &buf, seg_p);
  86.     buf = skip(buf);
  87.     if (*buf == '+')
  88.     {
  89.         v += value(skip(buf+1), &buf, seg_p);
  90.     }
  91.     else if (*buf == '-')
  92.     {
  93.         v -= value(skip(buf+1), &buf, seg_p);
  94.     }
  95.     *exp_p = v;
  96.     return skip(buf);
  97. }
  98.  
  99. long
  100. reg_addr(s)
  101.     char *s;
  102. {
  103.     long val;
  104.  
  105.     switch (*s++)
  106.     {
  107.     case    'a': case 'A': val = 32; break;
  108.     case    'd': case 'D': val = 0; break;
  109.     default: goto error;
  110.     }
  111.     if (*s >= '0' && *s <= '7')
  112.     {
  113.         return val + 4*(*s - '0');
  114.     }
  115.  
  116. error:
  117.     printf("Unknown register: %2.2s\n", s);
  118. /*    longjmp(mainlp); --jrb */
  119.     longjmp(mainlp, 1); /* ++jrb */
  120. }
  121.  
  122. long
  123. value(s, s_p, seg_p)
  124.     char *s, **s_p;
  125.     int *seg_p;
  126. {
  127.     long k;
  128.  
  129.     if (*s == '\'') /* handle character constants here */
  130.     {
  131.         *s_p = s + 2;
  132.         return s[1];
  133.     }
  134.     if (*s == '-' || isdigit(*s))
  135.     {
  136.         return strtol(s, s_p, 0);
  137.     }
  138.     if (*s == '$')
  139.     {
  140.         k = reg_addr(s+1);
  141.         *s_p = s + 3;
  142.         return ptrace(3, curpid, k, 0L);
  143.     }
  144.     return lookup(s, s_p, seg_p);
  145. }
  146.  
  147. long
  148. lookup(s, s_p, seg_p)
  149.     char *s, **s_p;
  150.     int *seg_p;
  151. {
  152.     extern long saddr;
  153.     char c;
  154.     int i, l;
  155.  
  156.     for (l = 1; idchar(s[l]); ++l ) {}
  157.     c = s[l]; s[l] = 0;
  158.     
  159.     if (strcmp("_start", s) == 0)
  160.     {
  161.         *seg_p = T;
  162.         *(*s_p = s + 6) = c;
  163.         return saddr;
  164.     }
  165.     for (i = 0; i < nsyms; i++)
  166.         if (strcmp(nbufp[i].on_mptr, s) == 0)
  167.         {
  168.             *seg_p = (nbufp[i].on_type & S_TYP) == S_MIN ? T : D;
  169.             *(*s_p = s + l) = c;
  170.             return nbufp[i].on_valu + saddr;
  171.         }
  172.  
  173.     printf("%s: symbol not found\n", s);
  174. /*    longjmp(mainlp); -- jrb */
  175.     longjmp(mainlp, 1); /* ++jrb */
  176. }
  177.  
  178. /******************END OF ORIGINAL CODE***********************/
  179.  
  180. /*
  181.  * The following code is actually a highly edited
  182.  * version of anm.c - The ACK version of nm
  183.  * That file's header follows:
  184.  */
  185.  
  186. /* @(#)anm.c    1.6 */
  187. /*
  188. **    print symbol tables for
  189. **    ACK object files
  190. **
  191. **    anm [-gopruns] [name ...]
  192. */
  193.  
  194. #define    ushort    unsigned short
  195.  
  196. long    off;
  197. #ifdef __STDC__
  198. void    *malloc(unsigned);
  199. void    *realloc(void *, unsigned);
  200. #else
  201. char    *malloc();
  202. char    *realloc();
  203. #endif
  204. long    s_base[S_MAX];    /* for specially encoded bases */
  205.  
  206. getsyms(file)
  207.     char *file;
  208. {
  209.     int    compare();
  210.     FILE        *fi;
  211.     struct    outsect    sbuf;
  212.     struct    outhead    hbuf;
  213.     struct    outname    nbuf;
  214.     char        *cbufp;
  215.     long        fi_to_co;
  216.     long        n;
  217.     unsigned    readcount;
  218.     int        j;
  219.  
  220.     fi = fopen(file,"r");
  221.     if (fi == NULL) {
  222.         fprintf(stderr, "db: cannot open %s\n", file);
  223.         return;
  224.     }
  225.  
  226.     getofmt((char *)&hbuf, SF_HEAD, fi);
  227.     if (BADMAGIC(hbuf)) {
  228.         fprintf(stderr, "db: %s-- bad format\n", file);
  229.         fclose(fi);
  230.         return;
  231.     }
  232.  
  233.     n = hbuf.oh_nname;
  234.     if (n == 0) {
  235.         fprintf(stderr, "db: %s-- no name list\n", file);
  236.         fclose(fi);
  237.         return;
  238.     }
  239.  
  240.     if (hbuf.oh_nchar == 0) {
  241.         fprintf(stderr, "db: %s-- no names\n", file);
  242.         fclose(fi);
  243.         return;
  244.     }
  245.     if ((readcount = hbuf.oh_nchar) != hbuf.oh_nchar) {
  246.         fprintf(stderr, "db: string area too big in %s\n", file);
  247.         exit(2);
  248.     }
  249.  
  250.     /* store special section bases */
  251.     if (hbuf.oh_flags & HF_8086) {
  252.         int i;
  253.         for (i=0; i<hbuf.oh_nsect; i++) {
  254.             getofmt((char *)&sbuf, SF_SECT, fi);
  255.             s_base[i+S_MIN] =
  256.                 (sbuf.os_base>>12) & 03777760;
  257.         }
  258.     }
  259.          
  260.     if ((cbufp = (char *)malloc(readcount)) == NULL) {
  261.         fprintf(stderr, "db: out of memory on %s\n", file);
  262.         exit(2);
  263.     }
  264.     fseek(fi, OFF_CHAR(hbuf), 0);
  265.     if (fread(cbufp, 1, readcount, fi) == 0) {
  266.         fprintf(stderr, "db: read error on %s\n", file);
  267.         exit(2);
  268.     }
  269.     fi_to_co = (long)cbufp - OFF_CHAR(hbuf);
  270.  
  271.     fseek(fi, OFF_NAME(hbuf), 0);
  272.     nsyms = 0;
  273.     while (--n >= 0) {
  274.         getofmt((char *)&nbuf, SF_NAME, fi);
  275.  
  276.         if (nbuf.on_foff == 0)
  277.             continue; /* skip entries without names */
  278.  
  279.         if ((nbuf.on_type&S_EXT)==0)
  280.             continue;
  281.  
  282.         nbuf.on_mptr = (char *)(nbuf.on_foff + fi_to_co);
  283.  
  284.         /* adjust value for specially encoded bases */
  285.         if (hbuf.oh_flags & HF_8086) {
  286.             if (((nbuf.on_type&S_ETC) == 0) ||
  287.             ((nbuf.on_type&S_ETC) == S_SCT)) {
  288.             j = nbuf.on_type&S_TYP;
  289.             if ((j>=S_MIN) && (j<=S_MAX))
  290.                 nbuf.on_valu += s_base[j];
  291.             }
  292.         }
  293.  
  294.         if (nbufp == NULL)
  295.             nbufp = (struct outname *)malloc(sizeof(struct outname));
  296.         else
  297.             nbufp = (struct outname *)realloc(nbufp, (nsyms+1)*sizeof(struct outname));
  298.         if (nbufp == NULL) {
  299.             fprintf(stderr, "db: out of memory on %s\n", file);
  300.             exit(2);
  301.         }
  302.         nbufp[nsyms++] = nbuf;
  303.     }
  304.  
  305.     qsort(nbufp, nsyms, sizeof(struct outname), compare);
  306.  
  307.     fclose(fi);
  308. }
  309.  
  310. compare(p1, p2)
  311. struct outname    *p1, *p2;
  312. {
  313.     if (p1->on_valu < p2->on_valu) return -1;
  314.     if (p1->on_valu > p2->on_valu) return 1;
  315.     return 0;
  316. }
  317.  
  318. getofmt(p, s, f)
  319. register char    *p;
  320. register char    *s;
  321. register FILE    *f;
  322. {
  323.     register i;
  324.     register long l;
  325.  
  326.     for (;;) {
  327.         switch (*s++) {
  328. /*        case '0': p++; continue; */
  329.         case '1':
  330.             *p++ = getc(f);
  331.             continue;
  332.         case '2':
  333.             i = getc(f);
  334.             i |= (getc(f) << 8);
  335.             *((short *)p) = i; p += sizeof(short);
  336.             continue;
  337.         case '4':
  338.             l = (long)getc(f);
  339.             l |= ((long)getc(f) << 8);
  340.             l |= ((long)getc(f) << 16);
  341.             l |= ((long)getc(f) << 24);
  342.             *((long *)p) = l; p += sizeof(long);
  343.             continue;
  344.         default:
  345.         case '\0':
  346.             break;
  347.         }
  348.         break;
  349.     }
  350. }
  351.